//
//  UserModelDataSource.swift
//  travelMapMvvm-swift2
//
//  Created by green on 15/11/3.
//  Copyright © 2015年 travelMapMvvm-swift2. All rights reserved.
//

import Foundation
import ReactiveCocoa
import AFNetworking
import TMCommonLib
import JSONHelper
import SwiftDate
import OpenShare

public class UserModelDataSource: UserModelDataSourceProtocol {
    
    public class func shareInstance()->UserModelDataSourceProtocol{
        struct YRSingleton{
            static var predicate:dispatch_once_t = 0
            static var instance:UserModelDataSource? = nil
        }
        dispatch_once(&YRSingleton.predicate,{
            YRSingleton.instance=UserModelDataSource()
        })
        return YRSingleton.instance!
    }
    
    // MARK: - 手机登录
    
    public func telephoneLogin(telephone: String, password: String) -> RACSignal {
        
        return RACSignal.createSignal({ (subscriber:RACSubscriber!) -> RACDisposable! in
            
            let parameters: [String:String] = ["telephone":telephone,"password":password]
            
            let manager = AFHTTPRequestOperationManager()
            manager.responseSerializer.acceptableContentTypes = NSSet(array: ["text/html","text/plain"]) as Set<NSObject>
            
            manager.POST(kURL+"telephonelogin", parameters: parameters, success: { (operation, responseObj) -> Void in
                
                let resultDic = responseObj as! [NSObject:AnyObject]
                
                let success = resultDic[kSuccess] as? Int
                let msg     = resultDic[kMsg] as? String
                
                if success == 0 {
                    
                    var user:UserModel?
                    
                    user <-- resultDic[kData]
                    
                    subscriber.sendNext(user)
                    subscriber.sendCompleted()
                    
                } else {
                    
                    subscriber.sendError(DataError.TelephoneLoginError(msg).error)
                }
                
            }) { (operation, error) -> Void in
                
                subscriber.sendError(DataError.TelephoneLoginError(nil).error)
            }
            
            return nil
        })
    }
    
    // MARK: - 新浪登录
    
    public func sinaLogin() -> RACSignal {
        
        return RACSignal.createSignal({ (subscriber:RACSubscriber!) -> RACDisposable! in
            
            OpenShare.WeiboAuth("", redirectURI: "http://openshare.gfzj.us/", success: { (resultDic:[NSObject : AnyObject]!) -> Void in
                
                let openid      = resultDic["userID"] as! Int
                let accesToken  = resultDic["accessToken"] as! String
                print("微博登录授权成功:\n\(resultDic)")
                
                self.sinaLogin(accesToken, openId: String(openid)).subscribeNext({ (any:AnyObject!) -> Void in
                    
                    subscriber.sendNext(any)
                    subscriber.sendCompleted()
                }, error: { (error:NSError!) -> Void in
                    
                    subscriber.sendError(error)
                })
                
            }, fail: { (resultDic:[NSObject : AnyObject]!, error:NSError!) -> Void in
                
                subscriber.sendError(DataError.SinaAuthError(nil).error)
                print("微博登录授权失败:\n\(resultDic)\n\(error)")
            })
            
            return nil
        })
    }
    
    /**
     * 新浪登录
     *
     * @param sinaOpenId 新浪开放平台ID
     *
     * @return 登录信号
     */
    private func sinaLogin(accessToken: String, openId: String) -> RACSignal {
        
        return RACSignal.createSignal({ (subscriber:RACSubscriber!) -> RACDisposable! in
            
            let parameters: [String:String] = ["sinaOpenId":openId]
            
            let manager = AFHTTPRequestOperationManager()
            manager.responseSerializer.acceptableContentTypes = NSSet(array: ["text/html","text/plain"]) as Set<NSObject>
            
            manager.POST(kURL+"sinalogin", parameters: parameters, success: { (operation, responseObj) -> Void in
                
                let resultDic = responseObj as! [NSObject:AnyObject]
                
                let success = resultDic[kSuccess] as? Int
                let msg     = resultDic[kMsg] as? String
                
                if success == 0 {
                    
                    var user:UserModel!
                    
                    user <-- resultDic[kData]
                    
                    if user.userPicUrl == nil || user.userPicUrl?.absoluteString == "" || user.userName == nil || user.userName == "" {
                        
                        self.modifyUInfoByQQ(user, accessToken: accessToken, openId: openId).subscribeNext({ (any:AnyObject!) -> Void in
                            
                            subscriber.sendNext(any)
                            subscriber.sendCompleted()
                        
                        }, error: { (error:NSError!) -> Void in
                            
                            subscriber.sendError(error)
                        })
                    } else {
                        
                        subscriber.sendNext(user)
                        subscriber.sendCompleted()
                    }
                    
                } else {
                    
                    subscriber.sendError(DataError.SinaLoginError(msg).error)
                }
                
            }) { (operation, error) -> Void in
                
                subscriber.sendError(DataError.SinaLoginError(nil).error)
            }
            
            return nil
        })
    }
    
    /**
     使用新浪用户信息覆盖原有用户信息
     http://open.weibo.com/wiki/2/users/show
     
     - parameter accessToken:
     - parameter openId:
     
     - returns:
     */
    private func modifyUInfoBySina(user:UserModel, accessToken:String,openId:String) -> RACSignal {
        
        return RACSignal.createSignal({ (subscriber:RACSubscriber!) -> RACDisposable! in
            
            let parameters: [String:String] = ["access_token":accessToken,"uid":openId]
            
            let manager = AFHTTPRequestOperationManager()
            manager.responseSerializer.acceptableContentTypes = NSSet(array: ["text/html","text/plain"]) as Set<NSObject>
            
            manager.POST("https://api.weibo.com/2/users/show.json", parameters: parameters, success: { (operation, responseObj) -> Void in
                
                let resultDic = responseObj as! [NSObject:AnyObject]
                let errorCode = resultDic["error_code"] as? String
                
                if let _=errorCode {
                    
                    let errorMsg = resultDic["error"] as! String
                    print("获取新浪用户信息成功:\n\(errorMsg)")
                    
                    subscriber.sendError(DataError.GetSinaUserInfoError(nil).error)
                    
                } else {
                    
                    print("获取新浪用户信息成功:\n\(resultDic)")
                    
                    let userName    = user.userName == nil || user.userName == "" ? resultDic["name"] as? String :user.userName
                    let userPicUrl  = user.userPicUrl?.absoluteString == nil || user.userPicUrl?.absoluteString == "" ? resultDic["profile_image_url"] as? String :user.userPicUrl?.absoluteString
                    
                    self.modifyUInfo(user.userId!, userName: userName, email: user.email, mobile: user.telephone, userPicUrl: userPicUrl).subscribeNext({ (any:AnyObject!) -> Void in
                        
                        subscriber.sendNext(any)
                        subscriber.sendCompleted()
                    }, error: { (error:NSError!) -> Void in
                        
                        subscriber.sendError(error)
                    })
                }
                
            }) { (operation, error) -> Void in
                
                subscriber.sendError(DataError.GetSinaUserInfoError(nil).error)
            }
            
            return nil
        })
    }
    
    // MARK: - 腾讯登录
    
    public func qqLogin() -> RACSignal {
        
        return RACSignal.createSignal({ (subscriber:RACSubscriber!) -> RACDisposable! in
            
            OpenShare.QQAuth("get_user_info", success: { (resultDic:[NSObject : AnyObject]!) -> Void in
                
                let openid      = resultDic["openid"] as! String
                let accessToken  = resultDic["access_token"] as! String
                print("腾讯登录授权成功:\n\(resultDic)")
                
                self.qqLogin(accessToken,openId:openid).subscribeNext({ (any:AnyObject!) -> Void in
                    
                    subscriber.sendNext(any)
                    subscriber.sendCompleted()
                }, error: { (error:NSError!) -> Void in
                    
                    subscriber.sendError(error)
                })
            }, fail: { (resultDic:[NSObject : AnyObject]!, error:NSError!) -> Void in
                
                subscriber.sendError(DataError.QQAuthError(nil).error)
                print("腾讯登录授权失败:\n\(resultDic)\n\(error)")
            })
            
            return nil
        })
    }
    
    /**
     * 腾讯登录
     *
     * @param qqOpenId 腾讯开放平台ID
     *
     * @return 登录信号
     */
    private func qqLogin(accessToken: String, openId: String) -> RACSignal {
        
        return RACSignal.createSignal({ (subscriber:RACSubscriber!) -> RACDisposable! in
            
            let parameters: [String:String] = ["qqOpenId":openId]
            
            let manager = AFHTTPRequestOperationManager()
            manager.responseSerializer.acceptableContentTypes = NSSet(array: ["text/html","text/plain"]) as Set<NSObject>
            
            manager.POST(kURL+"qqlogin", parameters: parameters, success: { (operation, responseObj) -> Void in
                
                let resultDic = responseObj as! [NSObject:AnyObject]
                
                let success = resultDic[kSuccess] as? Int
                let msg     = resultDic[kMsg] as? String
                
                if success == 0 {
                    
                    var user:UserModel!
                    
                    user <-- resultDic[kData]
                    
                    if user.userPicUrl == nil || user.userPicUrl?.absoluteString == "" || user.userName == nil || user.userName == "" {
                        
                        self.modifyUInfoByQQ(user, accessToken: accessToken, openId: openId).subscribeNext({ (any:AnyObject!) -> Void in
                            
                            subscriber.sendNext(any)
                            subscriber.sendCompleted()
                            
                        }, error: { (error:NSError!) -> Void in
                            
                            subscriber.sendError(error)
                        })
                    } else {
                        
                        subscriber.sendNext(user)
                        subscriber.sendCompleted()
                    }
                    
                } else {
                    
                    subscriber.sendError(DataError.QQLoginError(msg).error)
                }
                
            }) { (operation, error) -> Void in
                
                subscriber.sendError(DataError.QQLoginError(nil).error)
            }
            
            return nil
        })
    }
    
    /**
     使用腾讯用户信息覆盖原有用户信息
     http://wiki.open.qq.com/wiki/v3/user/get_info
     
     - parameter accessToken:
     - parameter openId:
     
     - returns:
     */
    private func modifyUInfoByQQ(user:UserModel, accessToken:String,openId:String) -> RACSignal {
        
        return RACSignal.createSignal({ (subscriber:RACSubscriber!) -> RACDisposable! in
            
            let parameters: [String:AnyObject] = ["openkey":accessToken,"openid":openId,"appid":kQQAppKey,"sig":kQQAppSecret,"pf":"qzone"]
            
            let manager = AFHTTPRequestOperationManager()
            manager.responseSerializer.acceptableContentTypes = NSSet(array: ["text/html","text/plain"]) as Set<NSObject>
            
            manager.POST("http://openapi.tencentyun.com/v3/user/get_info", parameters: parameters, success: { (operation, responseObj) -> Void in
                
                let resultDic = responseObj as! [NSObject:AnyObject]
                let ret = resultDic["ret"] as! Int
                
                if ret == 0 {
                    
                    print("获取腾讯用户信息成功:\n\(resultDic)")
                    
                    let userName    = user.userName == nil || user.userName == "" ? resultDic["nickname"] as? String :user.userName
                    let userPicUrl  = user.userPicUrl?.absoluteString == nil || user.userPicUrl?.absoluteString == "" ? resultDic["figureurl"] as? String :user.userPicUrl?.absoluteString
                    
                    self.modifyUInfo(user.userId!, userName: userName, email: user.email, mobile: user.telephone, userPicUrl: userPicUrl).subscribeNext({ (any:AnyObject!) -> Void in
                        
                        subscriber.sendNext(any)
                        subscriber.sendCompleted()
                    }, error: { (error:NSError!) -> Void in
                        
                        subscriber.sendError(error)
                    })
                } else {
                    
                    subscriber.sendError(DataError.GetQQUserInfoError(nil).error)
                    print("获取腾讯用户信息失败:\n\(resultDic)")
                }
                
            }) { (operation, error) -> Void in
                
                subscriber.sendError(DataError.GetQQUserInfoError(nil).error)
            }
            
            return nil
        })
    }
    
    // MARK: - 手机注册
    
    public func telephoneRegister(telephone: String, password: String) -> RACSignal {
        
        return RACSignal.createSignal({ (subscriber:RACSubscriber!) -> RACDisposable! in
            
            let parameters: [String:String] = ["telephone":telephone,"password":password]
            
            let manager = AFHTTPRequestOperationManager()
            manager.responseSerializer.acceptableContentTypes = NSSet(array: ["text/html","text/plain"]) as Set<NSObject>
            
            manager.POST(kURL+"telephoneregister", parameters: parameters, success: { (operation, responseObj) -> Void in
                
                let resultDic = responseObj as! [NSObject:AnyObject]
                
                let success = resultDic[kSuccess] as? Int
                let msg     = resultDic[kMsg] as? String
                
                if success == 0 {
                    
                    var user:UserModel?
                    
                    user <-- resultDic[kData]
                    
                    subscriber.sendNext(user)
                    subscriber.sendCompleted()
                    
                } else {
                    
                    subscriber.sendError(DataError.TelephoneRegisterError(msg).error)
                }
                
            }) { (operation, error) -> Void in
                
                subscriber.sendError(DataError.TelephoneRegisterError(nil).error)
            }
            
            return nil
        })
    }
    
    
    // MARK: - 忘记密码
    
    public func forgetPwd(telephone: String, password: String) -> RACSignal {
        
        return RACSignal.createSignal({ (subscriber:RACSubscriber!) -> RACDisposable! in
            
            let parameters: [String:AnyObject] = ["telephone":telephone,"password":password]
            
            let manager = AFHTTPRequestOperationManager()
            manager.responseSerializer.acceptableContentTypes = NSSet(array: ["text/html","text/plain"]) as Set<NSObject>
            
            manager.POST(kURL+"resetpwd", parameters: parameters, success: { (operation, responseObj) -> Void in
                
                let resultDic = responseObj as! [NSObject:AnyObject]
                
                let success = resultDic[kSuccess] as? Int
                let msg     = resultDic[kMsg] as? String
                
                if success == 0 {
                    
                    subscriber.sendNext(kSuccess)
                    subscriber.sendCompleted()
                } else {
                    
                    subscriber.sendError(DataError.ModifyPWDError(msg).error)
                }
                
            }) { (operation, error) -> Void in
                
                subscriber.sendError(DataError.ModifyPWDError(nil).error)
            }
            
            return nil
        })
    }
    
    // MARK: - 修改用户信息
    
    public func modifyUInfo(userId: Int, var userName: String?, var email: String?, var mobile: String?, var userPicUrl:String?) -> RACSignal {
        
        return RACSignal.createSignal({ (subscriber:RACSubscriber!) -> RACDisposable! in
            
            userName = userName == nil ? "" : userName
            email = email == nil ? "" : email
            mobile = mobile == nil ? "" : mobile
            userPicUrl = userPicUrl == nil ? "" : userPicUrl
            
            let parameters: [String:AnyObject] = ["userId":userId,"mobile":mobile!,"userName":userName!,"email":email!,"userPicUrl":userPicUrl!]
            
            let manager = AFHTTPRequestOperationManager()
            manager.responseSerializer.acceptableContentTypes = NSSet(array: ["text/html","text/plain"]) as Set<NSObject>
            
            manager.POST(kURL+"modifyuserinfo", parameters: parameters, success: { (operation, responseObj) -> Void in
                
                let resultDic = responseObj as! [NSObject:AnyObject]
                
                let success = resultDic[kSuccess] as? Int
                let msg     = resultDic[kMsg] as? String
                
                if success == 0 {
                    
                    var user:UserModel?
                    
                    user <-- resultDic[kData]
                    
                    subscriber.sendNext(user)
                    subscriber.sendCompleted()
                } else {
                    
                    subscriber.sendError(DataError.ModifyUInfoError(msg).error)
                }
                
            }) { (operation, error) -> Void in
                
                subscriber.sendError(DataError.ModifyUInfoError(nil).error)
            }
            
            return nil
        })
    }
    
    // MARK: - 上传头像
    
    public func uploadHeadImage(userId: Int, headImage: UIImage) -> RACSignal {
        
        return RACSignal.createSignal({ (subscriber:RACSubscriber!) -> RACDisposable! in
            
            let parameters: [String:AnyObject] = ["userId":userId]
            
            let manager = AFHTTPRequestOperationManager()
            manager.responseSerializer.acceptableContentTypes = NSSet(array: ["text/html","text/plain"]) as Set<NSObject>
            
            manager.POST(kURL+"uploadphoto", parameters: parameters, constructingBodyWithBlock: { (formData:AFMultipartFormData!) -> Void in
                
                let name = NSDate().toString(format: DateFormat.Custom("YYYY-MM-dd HH:mm:ss"))
                let tempImage = UIImageJPEGRepresentation(headImage, 1)!
                
                formData.appendPartWithInputStream(
                    NSInputStream(data: tempImage), name: name, fileName: "temp.jpg", length: Int64(tempImage.length), mimeType: "image/png")
            }, success: { (operation:AFHTTPRequestOperation!, responseObj:AnyObject!) -> Void in
                
                let resultDic = responseObj as! [NSObject:AnyObject]
                
                let success = resultDic[kSuccess] as? Int
                let msg     = resultDic[kMsg] as? String
                
                if success == 0 {
                    
                    var userPicUrl:NSURL?
                    
                    userPicUrl <-- resultDic[kData]
                    
                    subscriber.sendNext(userPicUrl)
                    subscriber.sendCompleted()
                    
                } else {
                    
                    subscriber.sendError(DataError.UploadHeadPhotoError(msg).error)
                }
                
            }, failure: { (operation:AFHTTPRequestOperation!, error:NSError!) -> Void in
                
                subscriber.sendError(DataError.UploadHeadPhotoError(nil).error)
            })
            
            return nil
        })
    }
    
    
    // MARK: - 保存登录用户信息
    
    public func saveUser(user: UserModel) {
        
        NSUserDefaults.standardUserDefaults().setObject(NSKeyedArchiver.archivedDataWithRootObject(user),forKey:kLoginUserKey)
        NSUserDefaults.standardUserDefaults().synchronize()
    }
    
    
    // MARK: - 清除登录用户信息
    
    public func clearUser() {
        
        NSUserDefaults.standardUserDefaults().removeObjectForKey(kLoginUserKey)
        NSUserDefaults.standardUserDefaults().synchronize()
    }
    
    
    // MARK: - 查询登录用户信息
    
    public func queryUser() -> UserModel? {
        
        let loginUserData   = NSUserDefaults.standardUserDefaults().objectForKey(kLoginUserKey) as? NSData
        
        if let loginUserData=loginUserData {
            
            let loginUser = NSKeyedUnarchiver.unarchiveObjectWithData(loginUserData) as? UserModel
            
            if let userPicUrl=loginUser?.userPicUrl {
                
                loginUser?.userPhotoInfo = PhotoInfo(sourceImageURL: userPicUrl)
                return loginUser
            }
        }
        return nil
    }
    
    
    // MARK: - 查询登录页面默认显示的手机号
    
    public func queryLoginPageDefaultTelephone() -> String {
        
        if let defaultTel = NSUserDefaults.standardUserDefaults().stringForKey(kLoginPageDefaultTelephone) {
            
            return defaultTel
        } else {
            
            return ""
        }
    }
    
    // MARK: - 保存登录页面默认显示的手机号
    
    public func saveLoginPageDefaultTelephone(defaultTelephone: String) {
        
        NSUserDefaults.standardUserDefaults().setObject(defaultTelephone,forKey:kLoginPageDefaultTelephone)
        NSUserDefaults.standardUserDefaults().synchronize()
    }
    
}